The Global Refugee Crisis

Author

Khushboo Pursnani

Introduction

As of 2024, over 122 million people are displaced globally — yet the burden is far from equally shared. This report highlights that low- and middle-income countries, particularly in Africa and Asia, host the vast majority of the world’s refugees, often with limited infrastructure and strained resources. Countries such as Pakistan, Chad, and Uganda face disproportionate pressure, with refugees making up over 10% of their population in some cases.

In contrast, many high-income nations, despite their economic strength, host far fewer refugees, both in absolute terms and relative to population. This raises critical concerns about global equity, shared responsibility, and the disproportionate impact of displacement on already vulnerable regions.

Refugee trends have not been static. Between 2011 and 2017, countries such as Uganda, Sudan, and Ethiopia experienced sharp surges in refugee populations, driven largely by ongoing regional conflicts. While some areas have seen stabilization, countries like Chad and Pakistan continue to receive large inflows of displaced individuals, placing further strain on their social and economic systems.

This report also explores whether wealthier countries are stepping up to the crisis. The data reveals a consistent pattern: displacement does not follow economic power. Many of the world’s largest refugee-hosting countries are among the least wealthy. While countries like Jordan and Iran continue to play a key role, many affluent nations contribute significantly less per capita, raising questions of fairness in the global refugee response.

Displacement is rising — but global responsibility remains uneven. As conflict, climate, and inequality continue to drive forced migration, the world must do more to share the weight.

Code
from google.colab import drive
drive.mount("/content/drive")
Mounted at /content/drive
Code
!pip install plotnine pandas geopandas
import pandas as pd
from plotnine import *
import geopandas as gpd
Requirement already satisfied: plotnine in /usr/local/lib/python3.11/dist-packages (0.14.5)
Requirement already satisfied: pandas in /usr/local/lib/python3.11/dist-packages (2.2.2)
Requirement already satisfied: geopandas in /usr/local/lib/python3.11/dist-packages (1.0.1)
Requirement already satisfied: matplotlib>=3.8.0 in /usr/local/lib/python3.11/dist-packages (from plotnine) (3.10.0)
Requirement already satisfied: mizani~=0.13.0 in /usr/local/lib/python3.11/dist-packages (from plotnine) (0.13.3)
Requirement already satisfied: numpy>=1.23.5 in /usr/local/lib/python3.11/dist-packages (from plotnine) (2.0.2)
Requirement already satisfied: scipy>=1.8.0 in /usr/local/lib/python3.11/dist-packages (from plotnine) (1.14.1)
Requirement already satisfied: statsmodels>=0.14.0 in /usr/local/lib/python3.11/dist-packages (from plotnine) (0.14.4)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.11/dist-packages (from pandas) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.11/dist-packages (from pandas) (2025.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.11/dist-packages (from pandas) (2025.2)
Requirement already satisfied: pyogrio>=0.7.2 in /usr/local/lib/python3.11/dist-packages (from geopandas) (0.10.0)
Requirement already satisfied: packaging in /usr/local/lib/python3.11/dist-packages (from geopandas) (24.2)
Requirement already satisfied: pyproj>=3.3.0 in /usr/local/lib/python3.11/dist-packages (from geopandas) (3.7.1)
Requirement already satisfied: shapely>=2.0.0 in /usr/local/lib/python3.11/dist-packages (from geopandas) (2.1.0)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.8.0->plotnine) (1.3.2)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.8.0->plotnine) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.8.0->plotnine) (4.57.0)
Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.8.0->plotnine) (1.4.8)
Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.8.0->plotnine) (11.1.0)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.8.0->plotnine) (3.2.3)
Requirement already satisfied: certifi in /usr/local/lib/python3.11/dist-packages (from pyogrio>=0.7.2->geopandas) (2025.1.31)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.11/dist-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)
Requirement already satisfied: patsy>=0.5.6 in /usr/local/lib/python3.11/dist-packages (from statsmodels>=0.14.0->plotnine) (1.0.1)
Code
import pandas as pd

# Path to your Excel file in Drive
file_path = '/content/drive/MyDrive/Colab Notebooks/UNICEF_Regional_Metadata_Merged_Final.xlsx'

# Read the first sheet into a DataFrame
df = pd.read_excel(file_path, engine='openpyxl')

# (Optional) Peek at the top to verify it loaded correctly
df.head()
country alpha_2_code alpha_3_code numeric_code indicator time_period obs_value sex unit_multiplier unit_of_measure ... inflation_consumer_prices_annual life_expectancy_at_birth_total_years military_expenditure_of_gdp fossil_fuel_energy_consumption_of_total gdp_growth_annual birth_rate_crude_per_1_000_people hospital_beds_per_1_000_people un_sub_region world_bank_income_groups_combined population_total
0 Afghanistan AF AFG 4 Refugees by host country, per 1 USD GNI per ca... 2003 0 Total NaN per 1 USD GNI per capita ... NaN 57.344 NaN NaN 8.832278 47.350 0.39 Southern Asia Low Income 22733049.0
1 Afghanistan AF AFG 4 Refugees by host country, per 1 USD GNI per ca... 2004 0 Total NaN per 1 USD GNI per capita ... NaN 57.944 2.431254 NaN 1.414118 46.330 0.39 Southern Asia Low Income 23560654.0
2 Afghanistan AF AFG 4 Refugees by host country, per 1 USD GNI per ca... 2005 0 Total NaN per 1 USD GNI per capita ... 12.686269 58.361 1.992066 NaN 11.229715 45.263 0.42 Southern Asia Low Income 24404567.0
3 Afghanistan AF AFG 4 Refugees by host country, per 1 USD GNI per ca... 2006 0 Total NaN per 1 USD GNI per capita ... 6.784597 58.684 1.896234 NaN 5.357403 44.721 0.42 Southern Asia Low Income 25424094.0
4 Afghanistan AF AFG 4 Refugees by host country, per 1 USD GNI per ca... 2007 0 Total NaN per 1 USD GNI per capita ... 8.680571 59.111 2.566267 NaN 13.826320 43.858 0.42 Southern Asia Low Income 25909852.0

5 rows × 24 columns

Code
# Summarize total refugees by UN Region
bar_data = (
    df.groupby('un_region')['obs_value']
    .sum()
    .reset_index()
    .rename(columns={'obs_value': 'Total_Refugees'})
)
Code
# Summarize total refugees by UN Region
bar_data = (
    df.groupby('un_region')['obs_value']
    .sum()
    .reset_index()
    .rename(columns={'obs_value': 'Total_Refugees'})
)

# Plot the bar chart nicely
(
    ggplot(bar_data, aes(x='un_region', y='Total_Refugees', fill='un_region')) +
    geom_bar(stat='identity') +
    scale_fill_brewer(type='seq', palette='Blues') +
    labs(
        title='Total Refugees by UN Region',
        x='UN Region',
        y='Number of Refugees'
    ) +
    theme_minimal() +
    theme(
        axis_text_x=element_text(angle=45, hjust=1)  # Rotates the x-axis labels
    )
)

Total Refugees by UN Region

Africa and Asia bear the heaviest refugee burdens globally, hosting significantly larger displaced populations compared to other regions. Africa alone accounts for the highest number of refugees, followed closely by Asia. In contrast, regions such as Europe, Latin America, and Northern America contribute relatively less to global refugee hosting, highlighting geographic inequalities in refugee support. This disparity underscores the need for international collaboration to better distribute the humanitarian burden.

Code
# Line Chart - Top 5 Host Countries Over Time

from plotnine import *

# Top 5 countries by total refugee hosting
top_countries = df.groupby('country')['obs_value'].sum().nlargest(5).index
line_data = df[df['country'].isin(top_countries)]

# Plot
(
    ggplot(line_data, aes(x='time_period', y='obs_value', color='country')) +
    geom_line(size=1.2) +
    labs(
        title="Refugee Trends Over Time - Top 5 Host Countries",
        x="Year",
        y="Number of Refugees"
    ) +
    scale_color_brewer(type='qual', palette='Set1') +  # Stronger, readable colors
    theme_minimal() +
    theme(
        axis_text_x=element_text(size=10),
        axis_text_y=element_text(size=10),
        plot_title=element_text(size=14, weight="bold", ha="center"),
        figure_size=(10, 5)
    )
)

Wealth vs Refugees Hosted

This scatter plot explores the relationship between a country’s wealth (GDP per capita) and the average number of refugees it hosts.
The visualization reveals that wealthier nations tend to host fewer refugees relative to their income levels, while lower-income countries carry a disproportionately higher refugee burden. Each point represents a country, and one can hover to discover specific details. The pattern underscores the imbalance in global refugee support responsibilities.

Code
!pip install plotly
Requirement already satisfied: plotly in /usr/local/lib/python3.11/dist-packages (5.24.1)
Requirement already satisfied: tenacity>=6.2.0 in /usr/local/lib/python3.11/dist-packages (from plotly) (9.1.2)
Requirement already satisfied: packaging in /usr/local/lib/python3.11/dist-packages (from plotly) (24.2)
Code
# First, create a new column for refugees per population (%)

df['refugees_per_population_%'] = (df['obs_value'] / df['population_total']) * 100
Code
import plotly.express as px

# Create choropleth map
fig = px.choropleth(
    df,
    locations="country",
    locationmode="country names",
    color="refugees_per_population_%",
    color_continuous_scale="Blues_r",  # reversed so high values are darker
    title="Refugees per Population (%) by Country",
    labels={'refugees_per_population_%': 'Refugees per Population %'}
)

fig.update_layout(
    title_font=dict(size=22, family='Arial', color='black'),
    geo=dict(
        showframe=False,
        showcoastlines=True,
        projection_type="natural earth",
        fitbounds="locations"   # Zoom into the active countries
    ),
    coloraxis_colorbar=dict(title="Refugees per Population %")
)

fig.show()

Global Refugee Burden Relative to National Population

This choropleth map highlights refugee burdens as a share of national populations.
Countries like Chad, Uganda, and Sudan stand out with darker shades, signaling intense pressure relative to population size.
The visualization emphasizes the unequal humanitarian responsibilities across nations, prompting reflection on global solidarity efforts.